package com.balabala.gym_user.service.impl;
import com.balabala.gym_user.constant.VipCardConstant;
import com.balabala.gym_user.mapper.VipCardMapper;
import com.balabala.gym_user.pojo.dto.AddVipCardDTO;
import com.balabala.gym_user.pojo.dto.VipCardQueryDTO;
import com.balabala.gym_user.pojo.entity.*;
import com.balabala.gym_user.pojo.vo.VipCardPageVO;
import com.balabala.gym_user.pojo.vo.VipCardUpdateVO;
import com.balabala.gym_user.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author 何涛
 * @Date: 2023/05/01/ 15:00
 * @description 会员卡实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor

public class VipCardServiceImpl extends ServiceImpl<VipCardMapper, VipCard> implements VipCardService {
    @Autowired
    VipCardVenuesService vipCardVenuesService;
    @Autowired
    VenuesService venuesService;
    @Autowired
    UserVipCardService userVipCardService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    CourseVipCardService courseVipCardService;
    @Override
    public Boolean addVipCard(AddVipCardDTO addVipCardDto) {
        VipCard vipCard=new VipCard();
        BeanUtils.copyProperties(addVipCardDto,vipCard);
        Boolean res=save(vipCard);
        //添加会员卡和场馆的关系
        addVipCardDto.getVenuesId().forEach(venuesId->vipCardVenuesService.save(VipCardVenues.builder().vipCardId(vipCard.getId()).venuesId(venuesId).build()));

        return res;
    }

    @Override
    public PageInfo getVipCardPageList(VipCardQueryDTO vipCardQueryDto) {
        PageHelper.startPage(vipCardQueryDto.getPage(),vipCardQueryDto.getLimit());
        //根据条件查询
        LambdaQueryWrapper<VipCard> vipCardLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(vipCardQueryDto.getCardType()!=null){
            vipCardLambdaQueryWrapper.eq(VipCard::getCardType,vipCardQueryDto.getCardType());
        }
        if(!StringUtils.isEmpty(vipCardQueryDto.getName()))
        {
            vipCardLambdaQueryWrapper.like(VipCard::getName,vipCardQueryDto.getName());
        }
        List<VipCard> list = list(vipCardLambdaQueryWrapper);
        int i=1;
        List<VipCardPageVO> vipCardPageVOList =new ArrayList<>();
        for (VipCard vipCard : list) {
            VipCardPageVO vipCardPageVo=new VipCardPageVO();
            BeanUtils.copyProperties(vipCard,vipCardPageVo);
            vipCardPageVo.setOrder(i++);
            // 根据会员卡id查出所有场馆id
            List<VipCardVenues> vipCardVenues = vipCardVenuesService.list(new LambdaQueryWrapper<VipCardVenues>()
                    .eq(VipCardVenues::getVipCardId, vipCard.getId()));
            // 根据场馆id查询场馆
            vipCardVenues.forEach(vipCardVenues1 -> vipCardPageVo.getVenues().add(venuesService.getById(vipCardVenues1.getVenuesId())));
            vipCardPageVOList.add(vipCardPageVo);
        }
        return new PageInfo(vipCardPageVOList);
    }

    @Override
    public Boolean deleteVipCardById(Long id) {
        //删除会员卡和场馆关系数据
        vipCardVenuesService.remove(new LambdaQueryWrapper<VipCardVenues>().eq(VipCardVenues::getVipCardId,id));
        // 删除会员卡与用户的关系
        userVipCardService.remove(new LambdaQueryWrapper<UserVipCard>().eq(UserVipCard::getVipCardId,id));
        //删除会员卡与课程的对应关系
        courseVipCardService.remove(new LambdaUpdateWrapper<CourseVipCard>().eq(CourseVipCard::getVipCardId,id));
        //删除会员卡
        removeById(id);

        //删除该会员卡的相关缓存
        deleteCardCache(id);
        log.info("已删除会员卡id：{} 的缓存",id);
        return true;
    }

    @Override
    public VipCardUpdateVO findById(Long id) {
        //根据id查询会员卡
        VipCard vipCard = getById(id);
        VipCardUpdateVO vipCardUpdateVo=new VipCardUpdateVO();
        BeanUtils.copyProperties(vipCard,vipCardUpdateVo);
        //根据会员卡id查询对应的场馆id
        List<VipCardVenues> vipCardVenuesList = vipCardVenuesService.list(new LambdaQueryWrapper<VipCardVenues>().eq(VipCardVenues::getVipCardId, id));

        //根据场馆id查询场馆信息
        vipCardVenuesList.forEach(vipCardVenues -> vipCardUpdateVo.getVenues().add(venuesService.getById(vipCardVenues.getVenuesId())==null?new Venues() :new Venues()));

        return vipCardUpdateVo;
    }

    @Override
    public Boolean updateVipCard(VipCardUpdateVO vipCardUpdateVo) {
        //先删除这个会员卡对应的场馆的信息
        vipCardVenuesService.remove(new LambdaQueryWrapper<VipCardVenues>().eq(VipCardVenues::getVipCardId,vipCardUpdateVo.getId()));
        //修改会员卡信息
        VipCard vipCard=new VipCard();
        BeanUtils.copyProperties(vipCardUpdateVo,vipCard);
        updateById(vipCard);
        //添加会员卡与场馆对应关系
        vipCardUpdateVo.getVenues().forEach(venues -> vipCardVenuesService.save(VipCardVenues.builder().venuesId(venues.getId()).vipCardId(vipCard.getId()).build()));
        //删除该会员卡的相关缓存
        deleteCardCache(vipCardUpdateVo.getId());
        return true;
    }

    @Override
    public List<VipCard> getSupportVipCardByCourseId(Long courseId) {
        //从缓存中查询会员卡信息
        List<VipCard> vipCards = (List<VipCard>) redisTemplate.boundValueOps(VipCardConstant.CACHE_COURSE_SUPPORT_CARD + courseId).get();
        if(vipCards!=null){
            log.info("从redis中查到课程支持的会员卡，课程id：{}",courseId);
            return vipCards;
        }
        log.info("从数据库查询支持的会员卡，课程id：{}",courseId);
        vipCards = getBaseMapper().getSupportVipCardByCourseId(courseId);
        //把数据放入redis
        redisTemplate.boundValueOps(VipCardConstant.CACHE_COURSE_SUPPORT_CARD+courseId).set(vipCards);
        redisTemplate.boundValueOps(VipCardConstant.CACHE_COURSE_SUPPORT_CARD).expire(VipCardConstant.CACHE_COURSE_SUPPORT_CARD_EXPIRE, TimeUnit.SECONDS);
        return vipCards;
    }

    @Override
    public List<VipCard> findByCardType(Integer cardType) {
        return  getBaseMapper().findByCardType(cardType);

    }

    @Override
    public void deleteCardCache(Long cardId) {
        //得到与该会员所有关联的课程id
        List<Long> courseIds = courseVipCardService.list(new LambdaQueryWrapper<CourseVipCard>().eq(CourseVipCard::getVipCardId, cardId))
                .stream().map(courseVipCard -> courseVipCard.getCourseId()).collect(Collectors.toList());
        courseIds.forEach(cId->redisTemplate.boundValueOps(VipCardConstant.CACHE_COURSE_SUPPORT_CARD+cId).expire(-1,TimeUnit.SECONDS));
    }
}
